package cn.tenmg.hibernate.plus.utils;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

import cn.tenmg.hibernate.plus.HibernateDSQLContext;
import cn.tenmg.sql.paging.SQLPagingDialect;

/**
 * 分页查询方言工具类
 * 
 * @author June
 * 
 * @since 1.0.0
 *
 */
public abstract class SQLPagingDialectUtils {

	private static final Map<String, SQLPagingDialect> DIALECTS = new HashMap<String, SQLPagingDialect>();

	private static final String PAGING_DIALECT_PREFIX = "paging.dialect.", JDBC_PRODUCT_NAME_SPLIT = ":",
			GET_INSTANCE_METHOD = "getInstance";

	@SuppressWarnings("unchecked")
	public static SQLPagingDialect getSQLPagingDialect(String url) {
		String tmp = url.substring(url.indexOf(JDBC_PRODUCT_NAME_SPLIT) + 1),
				product = tmp.substring(0, tmp.indexOf(JDBC_PRODUCT_NAME_SPLIT));
		SQLPagingDialect dialect = null;
		if (DIALECTS.containsKey(product)) {
			dialect = DIALECTS.get(product);
		} else {
			synchronized (DIALECTS) {
				if (DIALECTS.containsKey(product)) {
					dialect = DIALECTS.get(product);
				} else {
					String className = HibernateDSQLContext.getProperty(PAGING_DIALECT_PREFIX + product);
					try {
						Class<SQLPagingDialect> cls = (Class<SQLPagingDialect>) Class.forName(className);
						Method method;
						try {
							if ((method = cls.getMethod(GET_INSTANCE_METHOD)) != null) {
								try {
									dialect = (SQLPagingDialect) method.invoke(null);
								} catch (IllegalAccessException | IllegalArgumentException
										| InvocationTargetException e) {
									e.printStackTrace();
								}
							}
						} catch (NoSuchMethodException | SecurityException e) {
							try {
								dialect = cls.newInstance();
							} catch (InstantiationException | IllegalAccessException ex) {
								ex.printStackTrace();
							}
						}
					} catch (ClassNotFoundException e) {
						e.printStackTrace();
					}
					DIALECTS.put(product, dialect);
				}
			}
		}
		return dialect;
	}
}